package de.hdu.mfz.ctrl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import de.hdu.mfz.dao.MitfahrtDAO;
import de.hdu.mfz.dao.RouteDAO;
import de.hdu.mfz.dao.UserDAO;
import de.hdu.mfz.dto.AJAXMessage;
import de.hdu.mfz.dto.RouteZeile;
import de.hdu.mfz.model.Mitfahrt;
import de.hdu.mfz.model.Route;
import de.hdu.mfz.model.User;

@Controller
public class UserController {
	UserDAO userDAO;
	RouteDAO routeDAO;
	MitfahrtDAO mitfahrtDAO;
	LoginController loginCtrl; //im LoginController befindet sich die Hilfsfunktion zum prüfen der HTTPSession
	 
	public void setRouteDAO (RouteDAO r) {
		this.routeDAO = r;	
	}
	
	public void setUserDAO (UserDAO u) {
		this.userDAO = u;
	}
	
	public void setMitfahrtDAO (MitfahrtDAO m) {
		this.mitfahrtDAO = m;
	}
	
	public void setLoginCtrl(LoginController l) {
		this.loginCtrl = l;
	}
	
	/** Ein User in der Datenbank speichern. Prüfung der Eingabefelder wird durchgeführt.
	 * Pflichtfelder:
	 * <ul>
	 * 	<li>username</li>
	 *  <li>passwort</li>
	 * 	<li>vorname</li>
	 * 	<li>nachname</li>
	 * 	<li>email</li>
	 * 	<li>telefonnummer</li>

	 * </ul>
	 * 
	 * @param params Liste (Map<String, String>) der Eingabefelder
	 * @param session (HTTPSession, Wird von Swing übergeben) 
	 * @return Objekt vom Typ AJAXMessages. AJAXMessages.returnMessage enthält eine Nachricht an den Anwender (ggf. Fehlermeldung)
	 */
	@RequestMapping(value="/saveUser.json", method=RequestMethod.POST)
	public @ResponseBody AJAXMessage saveUser(@RequestParam Map<String, String> params, HttpSession session) {
		
		//  1. Formularfelder in lokale Variablen speichern 
		String par_username;
		String par_passwort;
		String par_vorname;
		String par_nachname;
		String par_email;
		String par_telefonnummer;
		
		try {
			par_username = params.get("username");
			par_passwort = params.get("passwort");
			par_vorname = params.get("vorname");
			par_nachname = params.get("nachname");
			par_email = params.get("email");
			par_telefonnummer = params.get("telefonnummer");
		} catch (Exception e) {
			//Fehler ausgeben, wenn übergebenes Formular unvollständig ist
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Schwerwiegender Fehler bei der Verarbeitung Ihrer Anfrage.");
		}		
		
		//  2. Eingabewerte umwandeln und prüfen 
		if (par_username.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie einen Usernamen ein!");
		}
		
		if (par_passwort.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie ein Passwort ein!");
		}
		
		if (par_vorname.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie einen Vornamen ein!");
		}
		
		if (par_nachname.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie einen Nachnamen ein!");
		}
		
		if (par_email.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie eine Email ein!");
		}
		
		if (par_telefonnummer.equals("")) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Bitte geben Sie eine Telefonnummer ein!");
		}
		
		
			
		/* For Debugging....
		String a = "";
		for (RouteZeile_Ort o : orteListe) {
			a = a + o.id + ": " + o.name;
		}
		return new AJAXMessage(false, AJAXMessage.FailureCode.InfoMessage, a);*/
		
		
		//******User speichern *******************************
		
		try {
			User u= new User(par_username, par_vorname, par_nachname, par_email, par_telefonnummer, par_passwort, false);
			userDAO.insert(u);
		} catch (Exception e) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.WarningMessage, "Schwerwiegender Fehler beim Speichern des neuen Users.");
		}	
		
		return new AJAXMessage(true, AJAXMessage.FailureCode.InfoMessage, "Der User wurde gespeichert.");		
	}
	
	
	/** Zeigt eine Liste mit den Routen zu einem User an.
	 * @author Katharina, Steffi
	 * @param session (HTTPSession, Wird von Swing uebergeben) 
	 * @return Objekt vom Typ AJAXMessages. AJAXMessages.returnMessage enthaelt eine Nachricht an den Anwender (ggf. Fehlermeldung)
	 * @throws 
	 * 
	 */
	@RequestMapping(value="/showRoutenUser.json", method=RequestMethod.POST)
	public @ResponseBody AJAXMessage searchRouteToUser(HttpSession session) {

		//Für diese Funktion ist ein Login erforderlich
		User myUser;
		try {
			myUser = loginCtrl.getUserFromSession(session);
		} catch (Exception e) {
			return new AJAXMessage(false, AJAXMessage.FailureCode.LoginRequired, e.getMessage());
		}

		//ArrayList für Ergebnis. ArrayList hat den Vorteil, dass nach FIFO sortiert wird.
		
		/** R O U T E N **/
		ArrayList<RouteZeile> retListe = new ArrayList<RouteZeile>();
		List<Route> routen;
		if (myUser.isAdmin())
			routen = routeDAO.findAll();
		else 
			routen = routeDAO.findByFahrer(myUser);
		
		//Für jede Route ein RouteZeile-Objekt erzeugen und in Ergebnis-Array speichern.
		for (Route r : routen)
			retListe.add(new RouteZeile(r, r.getStartzeit().toString(), r.getZielzeit().toString(),this.mitfahrtDAO.findByRoute(r).size()));
		
		/** M I T F A H R T E N     -    User mit isAdmin = true kann nirgends mitfahren.**/
		List<Mitfahrt> mitfahrten = mitfahrtDAO.findByMitfahrer(myUser);
		//Für jede Mein RouteZeile-Objekt erzeugen und in Ergebnis-Array speichern.
		for (Mitfahrt m : mitfahrten) {
			retListe.add(new RouteZeile(m.getRoute(), m.getRoute().getStartzeit().toString(), m.getRoute().getZielzeit().toString(),this.mitfahrtDAO.findByRoute(m.getRoute()).size()));
		}
	    return new AJAXMessage(true, AJAXMessage.FailureCode.None, retListe.toArray());
	}
}
